Device drivers are kernel modules embedded within an operating system kernel for controlling data transferred to and received from peripheral hardware devices. Some types of device drivers also perform resource allocation as a result of an I/O or configuration operation, such as kernel memory mappings, direct memory access (DMA) mapping of resources and interrupt line and vector allocations. The device drivers, unlike user applications, are usually situated beneath layers of other software, such as network protocol stacks and filesystems. The kernel interfaces with peripheral devices, such as file storage, graphical display and communication devices, via its device drivers. The technique employed by the kernel to interface with a particular device is device-dependent and each different type of device generally requires its own specific device driver.
Debugging and tracing the performance and operation of device drivers is problematic for several reasons. First, debugging kernel code, including device drivers, is more difficult than debugging user-level application code. The device drivers operate without the protection of the operating system and function much closer to the hardware than the application code. Second, device driver bugs can prove catastrophic. For instance, a stray pointer access can crash the entire system. Third, device drivers are relatively inaccessible. Device driver interfaces are within the kernel memory space and are not directly accessible by application programs. Moreover, some device driver functions can only be invoked via other device drivers, thereby making debugging via application programs impractical. Finally, efforts to debug and trace device drivers can adversely affect the operation and timing of the kernel. For instance, overly intrusive instrumentation can change the dynamics of the system and nullify the meaningfulness of the test results.
One approach to tracing device drivers under the Solaris.TM. operating system, a version of UNIX.RTM., uses the truss user command, such as described in the "SunOS Reference Manual," pp. 1-1043 to 1-1044, 1044; 1-1046 Sun Microsystems, Inc. (1997), the disclosure of which is incorporated herein by reference. The truss command traces system calls and signals by executing a specified command and tracing the system calls performed, signals received and machine faults incurred. However, the truss command is limited to tracing system call interactions occurring across the user and kernel memory space boundary and cannot trace inter-device driver calls. Solaris.TM. is a trademark of Sun Microsystems, Inc., Mountain View, Calif. UNIX.RTM. is a registered trademark of The Santa Cruz Operation, Santa Cruz, Calif.
Another approach to tracing device drivers under the Solaris.TM. operating system uses the snoop system administration command, such as described in the "SunOS Reference Manual," pp. 1M -790 to 1M-801, cited hereinabove, the disclosure of which is incorporated herein by reference. The snoop command possesses a built-in layering mechanism which captures packets from the network and displays their contents using both a network packet filter and streams buffer modules to capture packets from the network. However, the snoop command is limited to observing protocol transactions on a particular network or device by tracing network packets and cannot trace interactions for specific device drivers.
Therefore, there is a need for a system and method for tracing and debugging device drivers that is aware of device driver semantics. Such a system and method would observe incoming and outgoing system calls, identify the applications using device drivers, time stamp events and track resource allocation and usage within the device driver.